1 using System;
2 using
UnityEngine;
3 using
System.Collections.Generic;
4 using
System.Text;
5 using
Random = UnityEngine.Random;
6
7 namespace
ProceduralToolkit
8 {

9     ///
<summary>
10     ///
Class for generating random data. Contains extensions for arrays and other classes.
11     ///
</summary>
12     
public static class RandomE
13     {
14         
#region Vectors
15
16         ///
<summary>
17         ///
Returns a random point on a circle with radius 1
18         ///
</summary>
19         
public static Vector2 onUnitCircle2 { get { return PTUtils.PointOnCircle2(1, Random.Range(0, 360f)); } }
20
21         ///
<summary>
22         ///
Returns a random point on a circle with radius 1
23         ///
</summary>
24         
public static Vector2 onUnitCircle3XY { get { return PTUtils.PointOnCircle3XY(1, Random.Range(0, 360f)); } }
25
26         ///
<summary>
27         ///
Returns a random point on a circle with radius 1
28         ///
</summary>
29         
public static Vector2 onUnitCircle3XZ { get { return PTUtils.PointOnCircle3XZ(1, Random.Range(0, 360f)); } }
30
31         ///
<summary>
32         ///
Returns a random point on a circle with radius 1
33         ///
</summary>
34         
public static Vector2 onUnitCircle3YZ { get { return PTUtils.PointOnCircle3YZ(1, Random.Range(0, 360f)); } }
35
36         ///
<summary>
37         ///
Returns a random point inside a unit square
38         ///
</summary>
39         
public static Vector2 insideUnitSquare { get { return new Vector2(Random.value, Random.value); } }
40
41         ///
<summary>
42         ///
Returns a random point on the perimeter of a unit square
43         ///
</summary>
44         
public static Vector2 onUnitSquare { get { return PointOnSquare(1, 1); } }
45
46         ///
<summary>
47         ///
Returns a random point inside a unit cube
48         ///
</summary>
49         
public static Vector3 insideUnitCube { get { return new Vector3(Random.value, Random.value, Random.value); } }
50
51         
#endregion Vectors
52
53         
#region Colors
54
55         ///
<summary>
56         ///
Returns a random color between black [inclusive] and white [inclusive]
57         ///
</summary>
58         
public static Color color { get { return new Color(Random.value, Random.value, Random.value); } }
59
60         ///
<summary>
61         ///
Returns a color with random hue and maximum saturation and value in HSV model
62         ///
</summary>
63         
public static ColorHSV colorHSV { get { return new ColorHSV(Random.value, 1, 1); } }
64
65         ///
<summary>
66         ///
Returns a gradient between two random colors
67         ///
</summary>
68         
public static Gradient gradient { get { return ColorE.Gradient(color, color); } }
69
70         ///
<summary>
71         ///
Returns a gradient between two random HSV colors
72         ///
</summary>
73         
public static Gradient gradientHSV { get { return ColorE.Gradient(colorHSV, colorHSV); } }
74
75         ///
<summary>
76         ///
Returns a color with random hue and given <paramref name="saturation"/> and <paramref name="value"/>
77         ///
</summary>
78         
public static ColorHSV ColorHue(float saturation, float value, float alpha = 1)
79         {
80             
return new ColorHSV(Random.value, saturation, value, alpha);
81         }

82
83         ///
<summary>
84         ///
Returns a color with random saturation and given <paramref name="hue"/> and <paramref name="value"/>
85         ///
</summary>
86         
public static ColorHSV ColorSaturation(float hue, float value, float alpha = 1)
87         {
88             
return new ColorHSV(hue, Random.value, value, alpha);
89         }

90
91         ///
<summary>
92         ///
Returns a color with random value and given <paramref name="hue"/> and <paramref name="saturation"/>
93         ///
</summary>
94         
public static ColorHSV ColorValue(float hue, float saturation, float alpha = 1)
95         {
96             
return new ColorHSV(hue, saturation, Random.value, alpha);
97         }

98
99         ///
<summary>
100         ///
Returns a analogous palette based on a color with random hue
101         ///
</summary>
102         
public static List<ColorHSV> AnalogousPalette(
103             
float saturation = 1,
104             
float value = 1,
105             
float alpha = 1,
106             
int count = 2,
107             
bool withComplementary = false)
108         {
109             
return ColorHue(saturation, value, alpha).GetAnalogousPalette(count, withComplementary);
110         }

111
112         ///
<summary>
113         ///
Returns a triadic palette based on a color with random hue
114         ///
</summary>
115         
public static List<ColorHSV> TriadicPalette(
116             
float saturation = 1,
117             
float value = 1,
118             
float alpha = 1,
119             
bool withComplementary = false)
120         {
121             
return ColorHue(saturation, value, alpha).GetTriadicPalette(withComplementary);
122         }

123
124         ///
<summary>
125         ///
Returns a tetradic palette based on a color with random hue
126         ///
</summary>
127         
public static List<ColorHSV> TetradicPalette(float saturation = 1, float value = 1, float alpha = 1)
128         {
129             
return ColorHue(saturation, value, alpha).GetTetradicPalette();
130         }
131
132         
#endregion Colors
133
134         
#region Strings
135
136         ///
<summary>
137         ///
Returns a random alphanumeric 8-character string
138         ///
</summary>
139         
public static string string8 { get { return PTUtils.alphanumerics.GetRandom(8); } }
140
141         ///
<summary>
142         ///
Returns a random alphanumeric 16-character string
143         ///
</summary>
144         
public static string string16 { get { return PTUtils.alphanumerics.GetRandom(16); } }
145
146         ///
<summary>
147         ///
Returns a random lowercase letter
148         ///
</summary>
149         
public static char lowercaseLetter { get { return PTUtils.lowercase.GetRandom(); } }
150
151         ///
<summary>
152         ///
Returns a random uppercase letter
153         ///
</summary>
154         
public static char uppercaseLetter { get { return PTUtils.uppercase.GetRandom(); } }
155
156         
#endregion Strings
157
158         ///
<summary>
159         ///
Returns a random element
160         ///
</summary>
161         
public static T GetRandom<T>(this List<T> items)
162         {
163             
if (items == null)
164             {
165                 
throw new ArgumentNullException("items");
166             }
167             
if (items.Count == 0)
168             {
169                 Debug.LogError(
"Empty array");
170                 
return default(T);
171             }
172             
return items[Random.Range(0, items.Count)];
173         }

174
175         ///
<summary>
176         ///
Returns a random element
177         ///
</summary>
178         
public static T GetRandom<T>(this T[] items)
179         {
180             
if (items == null)
181             {
182                 
throw new ArgumentNullException("items");
183             }
184             
if (items.Length == 0)
185             {
186                 Debug.LogError(
"Empty array");
187                 
return default(T);
188             }
189             
return items[Random.Range(0, items.Length)];
190         }

191
192         ///
<summary>
193         ///
Returns a random element
194         ///
</summary>
195         
public static T GetRandom<T>(T item1, T item2, params T[] items)
196         {
197             
int index = Random.Range(0, items.Length + 2);
198             
if (index == 0)
199             {
200                 
return item1;
201             }
202             
if (index == 1)
203             {
204                 
return item2;
205             }
206             
return items[index - 2];
207         }

208
209         ///
<summary>
210         ///
Returns a random value from dictionary
211         ///
</summary>
212         
public static TValue GetRandom<TKey, TValue>(this Dictionary<TKey, TValue> dictionary)
213         {
214             
if (dictionary == null)
215             {
216                 
throw new ArgumentNullException("dictionary");
217             }
218             
var keys = dictionary.Keys;
219             
if (keys.Count == 0)
220             {
221                 Debug.LogError(
"Empty dictionary");
222                 
return default(TValue);
223             }
224             
return dictionary[new List<TKey>(keys).GetRandom()];
225         }

226
227         ///
<summary>
228         ///
Returns a random element with chances for roll of each element based on <paramref name="weights"/>
229         ///
</summary>
230         ///
<param name="weights">Positive floats representing chances</param>
231         
public static T GetRandom<T>(this List<T> list, List<float> weights)
232         {
233             
if (list == null)
234             {
235                 
throw new ArgumentNullException("list");
236             }
237             
if (list.Count == 0)
238             {
239                 Debug.LogError(
"Empty array");
240                 
return default(T);
241             }
242             
if (weights == null)
243             {
244                 
throw new ArgumentNullException("weights");
245             }
246             
if (weights.Count == 0)
247             {
248                 Debug.LogError(
"Empty weights");
249                 
return default(T);
250             }
251             
if (list.Count != weights.Count)
252             {
253                 Debug.LogError(
"Array sizes must be equal");
254                 
return list.GetRandom();
255             }
256
257             
if (list.Count == 1)
258             {
259                 
return list[0];
260             }
261
262             
var cumulative = new List<float>(weights);
263             
for (int i = 1; i < cumulative.Count; i++)
264             {
265                 cumulative[i] += cumulative[i -
1];
266             }
267
268             
float random = Random.Range(0, cumulative[cumulative.Count - 1]);
269             
int index = cumulative.FindIndex(a => a >= random);
270             
if (index == -1)
271             {
272                 Debug.LogError(
"Invalid weights");
273                 
return list.GetRandom();
274             }
275             
return list[index];
276         }

277
278         ///
<summary>
279         ///
Returns a random character from string
280         ///
</summary>
281         
public static char GetRandom(this string chars)
282         {
283             
if (string.IsNullOrEmpty(chars))
284             {
285                 Debug.LogError(
"Empty string");
286                 
return default(char);
287             }
288             
return chars[Random.Range(0, chars.Length)];
289         }

290
291         ///
<summary>
292         ///
Returns a random string consisting of characters from that string
293         ///
</summary>
294         
public static string GetRandom(this string chars, int length)
295         {
296             
if (string.IsNullOrEmpty(chars))
297             {
298                 Debug.LogError(
"Empty string");
299                 
return default(string);
300             }
301             
var randomString = new StringBuilder(length);
302             
for (int i = 0; i < length; i++)
303             {
304                 randomString.Append(chars[Random.Range(
0, chars.Length)]);
305             }
306             
return randomString.ToString();
307         }

308
309         ///
<summary>
310         ///
Returns a random element and removes it from list
311         ///
</summary>
312         
public static T PopRandom<T>(this List<T> items)
313         {
314             
if (items == null)
315             {
316                 
throw new ArgumentNullException("items");
317             }
318             
if (items.Count == 0)
319             {
320                 Debug.LogError(
"Empty array");
321                 
return default(T);
322             }
323             
var index = Random.Range(0, items.Count);
324             
var item = items[index];
325             items.RemoveAt(index);
326             
return item;
327         }

328
329         ///
<summary>
330         ///
Fisher–Yates shuffle
331         ///
</summary>
332         ///
<remarks>
333         ///
https://en.wikipedia.org/wiki/Fisher–Yates_shuffle
334         ///
</remarks>
335         
public static void Shuffle<T>(this T[] array)
336         {
337             
if (array == null)
338             {
339                 
throw new ArgumentNullException("array");
340             }
341             
for (int i = 0; i < array.Length; i++)
342             {
343                 
int j = Random.Range(i, array.Length);
344                 T tmp = array[j];
345                 array[j] = array[i];
346                 array[i] = tmp;
347             }
348         }

349
350         ///
<summary>
351         ///
Fisher–Yates shuffle
352         ///
</summary>
353         ///
<remarks>
354         ///
https://en.wikipedia.org/wiki/Fisher–Yates_shuffle
355         ///
</remarks>
356         
public static void Shuffle<T>(this List<T> array)
357         {
358             
if (array == null)
359             {
360                 
throw new ArgumentNullException("array");
361             }
362             
for (int i = 0; i < array.Count; i++)
363             {
364                 
int j = Random.Range(i, array.Count);
365                 T tmp = array[j];
366                 array[j] = array[i];
367                 array[i] = tmp;
368             }
369         }

370
371         ///
<summary>
372         ///
Returns true with probability from <paramref name="percent"/>
373         ///
</summary>
374         ///
<param name="percent">between 0.0 [inclusive] and 1.0 [inclusive]</param>
375         
public static bool Chance(float percent)
376         {
377             
if (percent == 0) return false;
378             
if (percent == 1) return true;
379             
return Random.value < percent;
380         }

381
382         ///
<summary>
383         ///
Returns a random point on the perimeter of a square with sides <paramref name="a"/> and <paramref name="b"/>
384         ///
</summary>
385         
public static Vector2 PointOnSquare(float a, float b)
386         {
387             
float value = Random.value*(2*a + 2*b);
388             
if (value < a)
389             {
390                 
return new Vector2(value, 0);
391             }
392             
value -= a;
393             
if (value < b)
394             {
395                 
return new Vector2(a, value);
396             }
397             
value -= b;
398             
if (value < a)
399             {
400                 
return new Vector2(value, b);
401             }
402             
return new Vector2(0, value - a);
403         }

404
405         ///
<summary>
406         ///
Returns a random point inside <paramref name="bounds"/>
407         ///
</summary>
408         
public static Vector3 PointInBounds(Bounds bounds)
409         {
410             
return Range(bounds.min, bounds.max);
411         }

412
413         ///
<summary>
414         ///
Returns a random vector between <paramref name="min"/> [inclusive] and <paramref name="max"/> [inclusive]
415         ///
</summary>
416         
public static Vector2 Range(Vector2 min, Vector2 max)
417         {
418             
return new Vector2(Random.Range(min.x, max.x), Random.Range(min.y, max.y));
419         }

420
421         ///
<summary>
422         ///
Returns a random vector between <paramref name="min"/> [inclusive] and <paramref name="max"/> [inclusive]
423         ///
</summary>
424         
public static Vector3 Range(Vector3 min, Vector3 max)
425         {
426             
return new Vector3(Random.Range(min.x, max.x), Random.Range(min.y, max.y), Random.Range(min.z, max.z));
427         }

428
429         ///
<summary>
430         ///
Returns a random vector between <paramref name="min"/> [inclusive] and <paramref name="max"/> [inclusive]
431         ///
</summary>
432         
public static Vector4 Range(Vector4 min, Vector4 max)
433         {
434             
return new Vector4(Random.Range(min.x, max.x), Random.Range(min.y, max.y), Random.Range(min.z, max.z),
435                 Random.Range(min.w, max.w));
436         }

437
438         ///
<summary>
439         ///
Returns a random float number between and <paramref name="min"/> [inclusive] and <paramref name="max"/> [inclusive].
440         ///
Ensures that there will be only specified amount of variants.
441         ///
</summary>
442         
public static float Range(float min, float max, int variants)
443         {
444             
if (variants < 2)
445             {
446                 Debug.LogError(
"Variants must be greater than one");
447                 variants =
2;
448             }
449             
return Mathf.Lerp(min, max, Random.Range(0, variants)/(variants - 1f));
450         }

451
452         ///
<summary>
453         ///
Returns a random vector between and <paramref name="min"/> [inclusive] and <paramref name="max"/> [inclusive].
454         ///
Ensures that there will be only specified amount of variants.
455         ///
</summary>
456         
public static Vector2 Range(Vector2 min, Vector2 max, int variants)
457         {
458             
return new Vector2(Range(min.x, max.x, variants), Range(min.y, max.y, variants));
459         }

460
461         ///
<summary>
462         ///
Returns a random vector between and <paramref name="min"/> [inclusive] and <paramref name="max"/> [inclusive].
463         ///
Ensures that there will be only specified amount of variants.
464         ///
</summary>
465         
public static Vector3 Range(Vector3 min, Vector3 max, int variants)
466         {
467             
return new Vector3(Range(min.x, max.x, variants), Range(min.y, max.y, variants),
468                 Range(min.z, max.z, variants));
469         }

470
471         ///
<summary>
472         ///
Returns a random vector between and <paramref name="min"/> [inclusive] and <paramref name="max"/> [inclusive].
473         ///
Ensures that there will be only specified amount of variants.
474         ///
</summary>
475         
public static Vector4 Range(Vector4 min, Vector4 max, int variants)
476         {
477             
return new Vector4(Range(min.x, max.x, variants), Range(min.y, max.y, variants),
478                 Range(min.z, max.z, variants), Range(min.w, max.w, variants));
479         }
480     }
481 }


Gõ tìm kiếm nhanh...